package cn.simple;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.simple.http.HttpFactory;
import cn.simple.http.HttpRequest;
import cn.simple.language.psi.*;
import cn.simple.language.psi.impl.SimpleGlobalConfigImpl;
import com.intellij.execution.lineMarker.RunLineMarkerContributor;
import com.intellij.icons.AllIcons;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public class SimpleRunLineMarkerContributor extends RunLineMarkerContributor {

    public SimpleRunLineMarkerContributor() {

    }

    @Nullable
    @Override
    public Info getInfo(@NotNull PsiElement psiElement) {
        if (psiElement instanceof LeafPsiElement) {
            if (SimpleTypes.HTTP_REQUEST_REGEXP.equals(((LeafPsiElement) psiElement).getElementType())) {
                HttpRequest httpRequest = HttpFactory.parse(psiElement.getText());
                if (httpRequest != null) {
                    httpRequest.setConfig(this.getConfig(psiElement));
                    return new Info(AllIcons.Actions.Execute, p -> "hello", new SimpleAnAction(httpRequest));
                }
            }
        }
        return null;
    }

    private JSONObject getConfig(PsiElement psiElement) {
        try {
            if (psiElement.getParent().getParent().getParent().getFirstChild() instanceof SimpleGlobalConfig config) {
                return this.parseToJson(config.getJson());
            }
        } catch (Exception e) {
            // 忽略
        }
        return new JSONObject();
    }

    private JSONObject parseToJson(SimpleJson json) {
        if (json != null) {
            JSONObject root = this.parseToJson(json.getJsonObj());
            if(root != null) {
                return root;
            }
        }
        return new JSONObject();
    }

    private JSONObject parseToJson(SimpleJsonObj jsonObj) {
        if (jsonObj != null) {
            JSONObject root = new JSONObject();
            List<SimpleJsonObjItem> items = jsonObj.getJsonObjItemList();
            for (SimpleJsonObjItem item : items) {
                String key = this.toString(item.getJsonKey().getText());
                root.set(key, this.parseJsonValue(item.getJsonValue()));
            }
            return root;
        }
        return null;
    }

    private JSONArray parseToJson(SimpleJsonArray jsonArray) {
        JSONArray array = new JSONArray();
        for (SimpleJsonValue simpleJsonValue : jsonArray.getJsonValueList()) {
            array.add(this.parseJsonValue(simpleJsonValue));
        }
        return array;
    }

    private Object parseJsonValue(SimpleJsonValue jsonValue) {
        PsiElement str = jsonValue.getStr();
        if(str != null) {
            return this.toString(str.getText());
        }
        PsiElement num = jsonValue.getNum();
        if(num != null) {
            return num.getText();
        }
        SimpleJsonObj jsonObj = jsonValue.getJsonObj();
        if(jsonObj != null) {
            return this.parseToJson(jsonObj);
        }
        SimpleJsonArray jsonArray = jsonValue.getJsonArray();
        if(jsonArray != null) {
            return this.parseToJson(jsonArray);
        }
        return null;
    }

    private String toString(String text) {
        return text.replaceAll("^[`'\"](.+)[`'\"]$", "$1");
    }
}
